#include "globals.h"
#include "errno.h"
#include "types.h"

#include "mm/mm.h"
#include "mm/tlb.h"
#include "mm/mman.h"
#include "mm/page.h"

#include "proc/proc.h"

#include "util/string.h"
#include "util/debug.h"

#include "fs/vnode.h"
#include "fs/vfs.h"
#include "fs/file.h"

#include "vm/vmmap.h"
#include "vm/mmap.h"


/*
 * This function implements the mmap(2) syscall, but only
 * supports the MAP_SHARED, MAP_PRIVATE, MAP_FIXED, and
 * MAP_ANON flags.
 *
 * Add a mapping to the current process's address space.
 * You need to do some error checking; see the ERRORS section
 * of the manpage for the problems you should anticipate.
 * After error checking most of the work of this function is
 * done by vmmap_map(), but remember to clear the TLB.
 */
int
do_mmap(void *addr, size_t len, int prot, int flags,
        int fd, off_t off, void **ret)
{
	int retv=0;
	file_t *fp;
	fp = fget(fd);
	int dir=VMMAP_DIR_HILO;
	if (fp==NULL){
		return -EBADF;
	}
	/*if((prot!=PROT_NONE)||(!(prot|PROT_READ))||(!(prot|PROT_WRITE))||(!(prot|PROT_EXEC))){
		return -EINVAL;
	}*/
	if(((flags&MAP_SHARED)||(flags&MAP_PRIVATE)||(flags&MAP_FIXED)||(flags|MAP_ANON))==0){
		return -EINVAL;
	}

	/*more checking to be done*/

	
	retv= vmmap_map(curproc->p_vmmap,fp->f_vnode, ADDR_TO_PN((uint32_t)addr), ADDR_TO_PN((uint32_t)addr+len), prot, flags, off, dir,(vmarea_t **)ret);
	tlb_flush((uintptr_t)addr);
	KASSERT(NULL != curproc->p_pagedir);
    dbg(DBG_VM,"(GRADING 6.a)  curproc->p_pagedir is not NULL\n");
	return retv;

/*        NOT_YET_IMPLEMENTED("VM: do_mmap");
        return -1;*/
}


/*
 * This function implements the munmap(2) syscall.
 *
 * As with do_mmap() it should perform the required error checking,
 * before calling upon vmmap_remove() to do most of the work.
 * Remember to clear the TLB.
 */
int
do_munmap(void *addr, size_t len)
{
	int retv=0;
	if (len==0){
		return -EINVAL;
	}
	/*more checking to be done*/

	retv= vmmap_remove(curproc->p_vmmap, ADDR_TO_PN(addr), (uint32_t)len);
	tlb_flush((uintptr_t)addr);
	KASSERT(NULL != curproc->p_pagedir);
    dbg(DBG_VM,"(GRADING 6.b)  curproc->p_pagedir is not NULL\n");
	return retv;
/*        NOT_YET_IMPLEMENTED("VM: do_munmap");
        return -1;*/
}

